/*
 * PS/2 keyboard constants
 *
 * This file is part of PanicOS.
 *
 * PanicOS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * PanicOS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with PanicOS.  If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef _KBD_H
#define _KBD_H

#define KBSTATP 0x64 // kbd controller status port(I)
#define KBS_DIB 0x01 // kbd data in buffer
#define KBDATAP 0x60 // kbd data port(I)

#define NO 0

#define SHIFT (1 << 0)
#define CTL (1 << 1)
#define ALT (1 << 2)

#define CAPSLOCK (1 << 3)
#define NUMLOCK (1 << 4)
#define SCROLLLOCK (1 << 5)

#define E0ESC (1 << 6)

// Special keycodes
#define KEY_HOME 0xE0
#define KEY_END 0xE1
#define KEY_UP 0xE2
#define KEY_DN 0xE3
#define KEY_LF 0xE4
#define KEY_RT 0xE5
#define KEY_PGUP 0xE6
#define KEY_PGDN 0xE7
#define KEY_INS 0xE8
#define KEY_DEL 0xE9

// C('A') == Control-A
#define C(x) (x - '@')

static unsigned char shiftcode[256] = {
	[0x1D] CTL, [0x2A] SHIFT, [0x36] SHIFT, [0x38] ALT, [0x9D] CTL, [0xB8] ALT
};

static unsigned char togglecode[256] = {[0x3A] CAPSLOCK, [0x45] NUMLOCK, [0x46] SCROLLLOCK};

static unsigned char normalmap[256] = {
	NO,
	0x1B,
	'1',
	'2',
	'3',
	'4',
	'5',
	'6', // 0x00
	'7',
	'8',
	'9',
	'0',
	'-',
	'=',
	'\b',
	'\t',
	'q',
	'w',
	'e',
	'r',
	't',
	'y',
	'u',
	'i', // 0x10
	'o',
	'p',
	'[',
	']',
	'\n',
	NO,
	'a',
	's',
	'd',
	'f',
	'g',
	'h',
	'j',
	'k',
	'l',
	';', // 0x20
	'\'',
	'`',
	NO,
	'\\',
	'z',
	'x',
	'c',
	'v',
	'b',
	'n',
	'm',
	',',
	'.',
	'/',
	NO,
	'*', // 0x30
	NO,
	' ',
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	'7', // 0x40
	'8',
	'9',
	'-',
	'4',
	'5',
	'6',
	'+',
	'1',
	'2',
	'3',
	'0',
	'.',
	NO,
	NO,
	NO,
	NO, // 0x50
	[0x9C] '\n', // KP_Enter
	[0xB5] '/', // KP_Div
	[0xC8] KEY_UP,
	[0xD0] KEY_DN,
	[0xC9] KEY_PGUP,
	[0xD1] KEY_PGDN,
	[0xCB] KEY_LF,
	[0xCD] KEY_RT,
	[0x97] KEY_HOME,
	[0xCF] KEY_END,
	[0xD2] KEY_INS,
	[0xD3] KEY_DEL
};

static unsigned char shiftmap[256] = {
	NO,
	033,
	'!',
	'@',
	'#',
	'$',
	'%',
	'^', // 0x00
	'&',
	'*',
	'(',
	')',
	'_',
	'+',
	'\b',
	'\t',
	'Q',
	'W',
	'E',
	'R',
	'T',
	'Y',
	'U',
	'I', // 0x10
	'O',
	'P',
	'{',
	'}',
	'\n',
	NO,
	'A',
	'S',
	'D',
	'F',
	'G',
	'H',
	'J',
	'K',
	'L',
	':', // 0x20
	'"',
	'~',
	NO,
	'|',
	'Z',
	'X',
	'C',
	'V',
	'B',
	'N',
	'M',
	'<',
	'>',
	'?',
	NO,
	'*', // 0x30
	NO,
	' ',
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	'7', // 0x40
	'8',
	'9',
	'-',
	'4',
	'5',
	'6',
	'+',
	'1',
	'2',
	'3',
	'0',
	'.',
	NO,
	NO,
	NO,
	NO, // 0x50
	[0x9C] '\n', // KP_Enter
	[0xB5] '/', // KP_Div
	[0xC8] KEY_UP,
	[0xD0] KEY_DN,
	[0xC9] KEY_PGUP,
	[0xD1] KEY_PGDN,
	[0xCB] KEY_LF,
	[0xCD] KEY_RT,
	[0x97] KEY_HOME,
	[0xCF] KEY_END,
	[0xD2] KEY_INS,
	[0xD3] KEY_DEL
};

static unsigned char ctlmap[256] = {
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	NO,
	C('Q'),
	C('W'),
	C('E'),
	C('R'),
	C('T'),
	C('Y'),
	C('U'),
	C('I'),
	C('O'),
	C('P'),
	NO,
	NO,
	'\r',
	NO,
	C('A'),
	C('S'),
	C('D'),
	C('F'),
	C('G'),
	C('H'),
	C('J'),
	C('K'),
	C('L'),
	NO,
	NO,
	NO,
	NO,
	C('\\'),
	C('Z'),
	C('X'),
	C('C'),
	C('V'),
	C('B'),
	C('N'),
	C('M'),
	NO,
	NO,
	C('/'),
	NO,
	NO,
	[0x9C] '\r', // KP_Enter
	[0xB5] C('/'), // KP_Div
	[0xC8] KEY_UP,
	[0xD0] KEY_DN,
	[0xC9] KEY_PGUP,
	[0xD1] KEY_PGDN,
	[0xCB] KEY_LF,
	[0xCD] KEY_RT,
	[0x97] KEY_HOME,
	[0xCF] KEY_END,
	[0xD2] KEY_INS,
	[0xD3] KEY_DEL
};

#endif
